package com.mojo.jvm;

import sun.misc.Launcher;

import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;

/**
 * 类加载器打印路径
 *
 * @author <a href="mailto:mojo_jj@163.com">Mojo</a>
 * @since JDK1.8
 */
public class ClassLoaderPrintPath {
    public static void main(String[] args) {
        //jdk8
        URL[] urLs = Launcher.getBootstrapClassPath().getURLs();
        //打印启动类加载的jar路径
        System.out.println("启动类加载器");
        for (URL urL : urLs) {
            System.out.println("==>" + urL.toExternalForm());
        }
        //打印扩展类加载器加载的jar路径
        ClassLoader ext = ClassLoaderPrintPath.class.getClassLoader().getParent();
        PrintClassLoader("扩展类", ext);
        //打印应用类加载器加载的jar路径
        ClassLoader app = ClassLoaderPrintPath.class.getClassLoader();
        PrintClassLoader("应用类", app);


    }

    private static void PrintClassLoader(String name, ClassLoader cl) {
        if (cl == null) {
            System.out.println(name + " class loader is null");
        } else {
            System.out.println(name + " class loader ==>" + cl.toString());
            Object ucp = getField(cl, "ucp");
            Object path = getField(ucp, "path");
            List ps = (List) path;
            for (Object p : ps) {
                System.out.println("===>" + p);
            }
        }

    }

    private static Object getField(Object obj, String field) {
        try {
            Field f;
            if (obj instanceof URLClassLoader) {
                f = URLClassLoader.class.getDeclaredField(field);
            } else {
                f = obj.getClass().getDeclaredField(field);
            }
            f.setAccessible(true);
            return f.get(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
